package com.wujunshen.redis.custom;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Duration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;

/**
 * @author frank woo(吴峻申) <br>
 * email:<a href="mailto:frank_wjs@hotmail.com">frank_wjs@hotmail.com</a> <br>
 * @date 2020/2/7 5:33 下午 <br>
 */
public abstract class AbstractRedisCustomizer implements RedisCustomizer {
    @Value("${spring.application.name}")
    private String applicationName;
    
    /**
     * 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
     *
     * @return Jackson2JsonRedisSerializer
     */
    public static Jackson2JsonRedisSerializer<Object> getJackson2JsonRedisSerializer() {
        Jackson2JsonRedisSerializer<Object> serializer =
                new Jackson2JsonRedisSerializer<>(Object.class);
        
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        
        serializer.setObjectMapper(mapper);
        
        return serializer;
    }
    
    /**
     * 便于构建缓存配置，默认配置如下：
     * <li>值序列化使用：GenericFastJsonRedisSerializer
     * <li>缓存Key前缀自动附加应用名称：spring.application.name
     *
     * @param ttl 过期时间
     * @return 缓存配置
     */
    protected RedisCacheConfiguration buildCacheConfiguration(Duration ttl) {
        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(ttl)
                .serializeValuesWith(
                        RedisSerializationContext.SerializationPair.fromSerializer(
                                getJackson2JsonRedisSerializer()))
                .computePrefixWith(cacheName -> applicationName + ":" + cacheName + ":");
    }
    
    /**
     * 便于构建缓存配置，默认配置如下：
     * <li>值序列化使用：GenericFastJsonRedisSerializer
     * <li>缓存Key前缀自动附加应用名称：spring.application.name
     *
     * @param expireSeconds 过期时间，单位：秒
     * @return 缓存配置
     */
    protected RedisCacheConfiguration buildCacheConfiguration(int expireSeconds) {
        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(expireSeconds))
                .serializeValuesWith(
                        RedisSerializationContext.SerializationPair.fromSerializer(
                                getJackson2JsonRedisSerializer()))
                .computePrefixWith(cacheName -> applicationName + ":" + cacheName + ":");
    }
}
